package com.motorola.dp.jenkinsmonitor.service.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service("classService")
@SuppressWarnings({ "unchecked", "rawtypes" })
public final class DefaultClassService implements ClassService {

    private static SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat timeParser = new SimpleDateFormat("HH:mm:ss");

    @Value("#{stringService}")
    private StringService stringService;

    public Object convertStringToClass(String s, Class c) throws ParseException {
        if (c == String.class) {
            return s;
        } else if (c == Character.class) {
            if (s.length() > 0) {
                 return Character.valueOf(s.charAt(0));
            }
            return Character.valueOf('\u0000');
        } else if (c == Byte.class) {
            return Byte.valueOf(s);
        } else if (c == Short.class) {
            return Short.valueOf(s);
        } else if (c == Integer.class) {
            return Integer.valueOf(s);
        } else if (c == Long.class) {
            return Long.valueOf(s);
        } else if (c == Float.class) {
            return Float.valueOf(s);
        } else if (c == Date.class) {
            return dateParser.parse(s);
        } else if (c == Time.class) {
            Date d = timeParser.parse(s);
            Time t = new Time(d.getTime());
            return t;
        } else {
            throw new UnsupportedOperationException("Cannot convert \"" + s + "\" to " + c.getSimpleName());
        }
    }

    public String getSetterName(Field f) {
        String fieldName = f.getName();
        return "set" + stringService.capitalize(fieldName);
    }

    public String getGetterName(Field f) {
        String fieldName = f.getName();
        return "get" + stringService.capitalize(fieldName);
    }

    public Method getSetterMethod(Field f, Class c) throws NoSuchMethodException {
        String setterMethodName = getSetterName(f);
        Class setterParameterClass = f.getType();

        Method setterMethod = c.getMethod(setterMethodName, setterParameterClass);

        return setterMethod;
    }

    public Method getGetterMethod(Field f, Class c) throws NoSuchMethodException {
        String getterMethodName = getGetterName(f);
        Method getterMethod = c.getMethod(getterMethodName);

        return getterMethod;
    }

    public Object getFieldValue(Field field, Object object)
        throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Class objectClass = object.getClass();
        Method valueGetterMethod = getGetterMethod(field, objectClass);
        Object fieldValue = valueGetterMethod.invoke(object);
        return fieldValue;
    }

    public void setStringService(StringService stringService) {
        this.stringService = stringService;
    }

}
